package com.dq.service.section.impl;

import com.alibaba.fastjson.JSONObject;
import com.dq.domain.sys.role.SysRole;
import com.dq.domain.sys.role.SysRoleSection;
import com.dq.domain.sys.user.user.BossUser;
import com.dq.exception.customException.AdminException;
import com.dq.exception.customException.DqRuntimeException;
import com.dq.controller.in.section.SysSectionQuery;
import com.dq.controller.in.base.BaseAdminQuery;
import com.dq.mapper.section.SectionMapper;
import com.dq.vo.Vo;
import com.dq.domain.base.impl.BaseDaoImpl;
import com.dq.domain.org.Org;
import com.dq.domain.sys.section.SysSection;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.repository.BaseRepositories;
import com.dq.service.org.OrgService;
import com.dq.service.section.SysSectionService;
import com.dq.utils.TreeBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author cf
 */
@Service
public class SysSectionServiceImpl extends BaseRepositories implements SysSectionService {
    @Autowired
    private OrgService orgService;
    @Autowired
    private SectionMapper sectionMapper;

    @Override
    public List<Long> listByLng(BigDecimal lat, BigDecimal lng) {
        Map<String, Object> param = new HashMap<>(16);
        param.put("lat", lat);
        param.put("lng", lng);
        return sectionMapper.listByLng(param);
    }

    @Override
    public SysSection getNumberOne()  throws AdminException {
        SysSection section = dao.get(SysSection.class, 1L);
        if(section == null || section.getId() == null) {
            throw new DqRuntimeException("未初始化顶级组织部门");
        }

        return section;
    }

    @Override
    public SysSection save(SysSection section)  throws AdminException {
        // 获取 祖级列表, 并对父级对象验证
        orgService.getAncestors(section);
        // 重复对象验证
        orgService.repetitionObjectBySave(section);

        SysUser user = sysUserService.getUser();
        section.setCreateUser(user);
        section.setUpdateUser(user);

        SysSection save = sysSectionRepository.save(section);
        if(section.getRoleIds() != null && section.getRoleIds().size() > 0) {
            saveRoleSection(section, save);

        }

        return save;
    }

    private void saveRoleSection(SysSection section, SysSection save) {
        List<SysRoleSection> roleSections = new ArrayList<>();
        for (Long roleId : section.getRoleIds()) {
            SysRole role = dao.get(SysRole.class, roleId);
            if (role == null) {
                throw new AdminException("关联角色不存在, roleId: " + roleId);
            }
            SysRoleSection sysRoleSection = new SysRoleSection();
            sysRoleSection.setSysRole(role);
            sysRoleSection.setSection(save);
            roleSections.add(sysRoleSection);
        }
        if (roleSections.size() > 0) {
            sysRoleSectionRepository.saveAll(roleSections);
        }
    }
    private void delOldRoleSection(SysSection section) {
        List<SysRoleSection> roleSections = sysRoleSectionRepository.findByDeletedFalseAndSection(section);
        if (roleSections != null && roleSections.size() > 0) {
            sysRoleSectionRepository.deleteAll(roleSections);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysSection update(@Valid SysSection section)  throws AdminException {
        // 重复对象验证
        orgService.repetitionObject(section);

        if(section.getDeleted()) {
            List<BossUser> bossUserList = bossUserRepository.findByDeletedFalseAndSection(section);
            if(bossUserList != null && bossUserList.size() > 0) {
                throw new AdminException("该部门下还有用户");
            }
            delOldRoleSection(section);
        }else {
            if(section.getRoleIds() != null && section.getRoleIds().size() > 0) {
                delOldRoleSection(section);
                saveRoleSection(section, section);
            }
        }

        SysUser user = sysUserService.getUser();
        section.setUpdateUser(user);

        return sysSectionRepository.save(section);
    }

    /**
     * 组织部门/门店山删除
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) throws AdminException {
        if(id != null && id.toString().equals("1")) {
            throw new AdminException("默认顶级组织部门不能删除");
        }
        SysSection section = dao.get(SysSection.class, id);
        List<SysSection> list = sysSectionRepository.findByDeletedIsFalseAndParent(section);
        if (!list.isEmpty()) {
            throw new AdminException("请先删除子组织部门");
        }
        if(section instanceof Org) {
            orgService.delete(section.getId());
        }else {
            section.setDeleted(true);
            update(section);
        }
    }

    /**
     * 所有组织部门-树形列表
     */
    @Override
    public Vo<SysSection.Vo> listTree(SysSectionQuery sectionQuery) throws AdminException {
        Map<String, Object> query = sectionQuery.parseMap();
        query.remove("page");
        query.remove("size");

        boolean t = false;
        if(StringUtils.isNotBlank(sectionQuery.getSimpleName())) {
            query.put("simpleName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(sectionQuery.getSimpleName()));
            query.remove("simpleName");
            t = true;
        }
        if(StringUtils.isNotBlank(sectionQuery.getFullName())) {
            query.put("fullName" + BaseDaoImpl.likeSqlStr, BaseAdminQuery.likeSql(sectionQuery.getFullName()));
            query.remove("fullName");
            t = true;
        }

        String ids = "";
        SysUser loginUser = sysUserService.getUserInSection();
        SysSection sectionLogin = loginUser.getSection();
        if(StringUtils.isNotBlank(sectionLogin.getAncestors())) {
            ids = sectionLogin.getAncestors() + "," + sectionLogin.getId().toString();
        }else {
            ids = sectionLogin.getId().toString();
        }
        String format = String.format("and (FIND_IN_SET (%s, u.ancestors)>0 or u.id in (%s) )", sectionLogin.getId(), ids);
        query.put(BaseDaoImpl.HQL_FUNCTION, format);

        query.put("sidx", "sort");
        query.put("order", "asc");

        List<SysSection> list = dao.find(dao.query2Hql(SysSection.class, query), query);
        if(t) {
//            是否获取 所有下级
//            List<Category> sons = categoryRepository.findByParentCategoryInAndDeletedFalse(categoryList);
//            list.addAll(sons);
        }
        Set<SysSection.Vo> vos = new HashSet<>();
        list.forEach(section -> {
            vos.add((SysSection.Vo) section.toVO());
        });
        List<SysSection.Vo> tree = TreeBuilder.buildTreeSysSection(vos);

        JSONObject json = new JSONObject();
        json.put("list", vos);
        json.put("tree", tree);
        return new Vo(json);
    }

}